package org.example;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.security.spec.KeySpec;
import java.util.Base64;
import java.util.Random;

public class a {

    private static final int AES_KEY_SIZE = 256; // AES密钥长度
    private static final int SALT_BYTES = 128; // 盐的长度，以字节为单位
    private static final int PBKDF2_ITERATIONS = 10000; // PBKDF2迭代次数

    // 使用加盐哈希和PBKDF2密钥拉伸技术生成AES密钥
    private static SecretKey generateAESKey(String password, byte[] salt) throws Exception {
        // 创建PBE密钥工厂
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        // 从密码获取PBE密钥
        KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, PBKDF2_ITERATIONS, AES_KEY_SIZE);
        SecretKey tmp = factory.generateSecret(spec);
        // 转换为AES密钥
        return new SecretKeySpec(tmp.getEncoded(), "AES");
    }

    // 生成随机盐
    private static byte[] generateSalt() {
        SecureRandom random = new SecureRandom();
        byte[] salt = new byte[SALT_BYTES];
        random.nextBytes(salt);
        return salt;
    }

    // AES加密
    public static String encryptData(String data, String password) throws Exception {
        byte[] salt = generateSalt();
        SecretKey secretKey = generateAESKey(password, salt);
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] encryptedBytes = cipher.doFinal(data.getBytes());
        // 将盐和加密数据一起编码为Base64字符串
        return Base64.getEncoder().encodeToString(salt) + ":" + Base64.getEncoder().encodeToString(encryptedBytes);
    }

    // AES解密
    public static String decryptData(String encryptedData, String password) throws Exception {
        // 从Base64字符串中分离出盐和加密数据
        String[] parts = encryptedData.split(":");
        if (parts.length != 2) {
            throw new IllegalArgumentException("Invalid encrypted data format.");
        }
        byte[] salt = Base64.getDecoder().decode(parts[0]);
        byte[] encryptedBytes = Base64.getDecoder().decode(parts[1]);
        SecretKey secretKey = generateAESKey(password, salt);
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
        return new String(decryptedBytes);
    }

    // 主方法，用于演示加密和解密过程
    public static void main(String[] args) {
        try {
            String dataToEncrypt = "123456";
            String password = "dfgdfshsfghsf";

            // 加密数据
            String encryptedData = encryptData(dataToEncrypt, password);
            System.out.println("Encrypted Data: " + encryptedData);

            // 解密数据
            String decryptedData = decryptData(encryptedData, password);
            System.out.println("Decrypted Data: " + decryptedData);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
